package littlecyberwar.tool;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;

import littlecyberwar.ui.*;

// a common superclass for different kind of mouse action to game command
// i.e. move straight ahead
// rotate
// side step, etc.
public class MouseRotateLeftHandler extends MouseRotateHandler {
//  Point2D pivotP;
//  double startDragX, startDragY, pivotX, pivotY;
//  double startAngle;

  public MouseRotateLeftHandler() {
    super();
    // startDragX = -1;
    // startDragY = -1;
    id = H_ROTATELEFT;
	unitSelectedText = "Drag mouse around the unit left-front corner and release button to wheel unit.";
	noUnitSelectedText = "Click on unit to select for left wheel.";
  }

	public void startAction( MouseEvent e ) {
		super.startAction(e);		
	}
 
	double getCurrentDiameter(boolean isCombinedShape){
		double largestWidth= 0;
		if ( isCombinedShape == false ){
			// need to find the largest element
			for ( int i=0; i < selectedElements.size(); i++ ) {
				Element el = ((SelectedElementContainer)selectedElements.get(i)).element;
				double currWidth =el.getWidth(); 
				if ( currWidth > largestWidth ){
					largestWidth = currWidth;
				}
			}
			
		}else{
			/**			  
			 *if combined shape, then need to figure out the combined shape
			 * then take the distance from the center of the combined shape,
			 * the largestWidth is then the distance from the right front corner 
			 * of the rightmost unit, all the way to the pivot point
			 * 
			 * 1. transform all elements into the origin according to the selected element 
			 * 2. sort all the selected elements from left to right
			 * 3. take the left most unit and put into "possible" pile
			 * 4. any elements within 1/2 base width of another tile in the "possible" pile also joins the possible pile
			 * 5. Take the "front" most unit from the possible pile.
			 * 6. its left front is the pivot point 
			 */
			ArrayList sortList = createLeftFrontList( selectedElements );
	
			// now sort the containers. At the end the first element in the array
			// would be the left most
			Collections.sort(sortList);
			
			// now move anyone within 1/2 base width of the possible pile into the possible pile
			ArrayList possiblePile = new ArrayList(selectedElements.size());
						
			SecondaryGroupSortElementHolder poss = getSecondaryGroupSortElementHolder((GroupSortElementHolder)sortList.get(0));			
			possiblePile.add(poss);
			
			for ( int i=1; i < sortList.size(); i++ ) {
				GroupSortElementHolder currHolder = (GroupSortElementHolder)sortList.get(i);
				boolean isPossible = compareCloseElementsInGroupAlignment(currHolder, possiblePile);
				if ( isPossible ){
					poss = getSecondaryGroupSortElementHolder(currHolder);
					possiblePile.add(poss);	
				}
			}
			
			// now the possible pile will have to sorted by the along the Y axis
			// the smallest Y value will become the pivot element
			//
			Collections.sort(possiblePile);

			// setup the pivot point here
			poss = (SecondaryGroupSortElementHolder)possiblePile.get(0);	
			Element pivotEl = poss.cont.element;		
			pivotP = pivotEl.getFinalLeftFrontPoint();
			pivotX = pivotP.getX();
			pivotY = pivotP.getY();
			
			// calculate dist from left front to right front of rightmost element
			GroupSortElementHolder rightMostHolder = (GroupSortElementHolder)(sortList.get(sortList.size()-1));
			Point2D rightMostPoint = rightMostHolder.cont.element.getFinalRightFrontPoint();
						
			largestWidth=rightMostPoint.distance(pivotP);
		}
		return(largestWidth);
	}
 
	SecondaryGroupSortElementHolder getSecondaryGroupSortElementHolder(GroupSortElementHolder gh ){
		SecondaryGroupSortElementHolder poss = new SecondaryGroupSortElementHolder();
		poss.cont = gh.cont;
		poss.refPointX = gh.refPointX;
		poss.refPointY = gh.refPointY; 
		return ( poss );		
	}
 	/**
 	 * If the currHolder refPointX coordinate is < 1/2 of the width of any other
 	 * @param currHolder
 	 * @param possiblePile
 	 * @return true if this is also a possible pile
 	 */ 
	boolean compareCloseElementsInGroupAlignment(
		GroupSortElementHolder currHolder, 
		ArrayList possiblePile) {
		
		boolean val = false;
		
		for ( int i=0; i < possiblePile.size(); i++ ){
			SecondaryGroupSortElementHolder h = (SecondaryGroupSortElementHolder)possiblePile.get(i);
			double x = h.refPointX;
			double halfwidth = h.cont.element.getWidth() /2;
			if ( currHolder.refPointX < (x+halfwidth)) {
				val = true;
				break;
			}
		}
		return ( val );
	}

	// must be called after getCurrentDiameter()
  void setGroupPivotParam() {	
	for ( int i=0; i < selectedElements.size(); i++ ){
		SelectedElementContainer cont = ((SelectedElementContainer)selectedElements.get(i));
		
		/**
		 * For the halfHeight and halfWidth, we have to take the pivotX,
		 * inverse transform it back to the coordinate of the shape 
		 */
		Element el = cont.element;
		AffineTransform elTrans = el.getTransform();
		Point2D invTransedPivotP = null;
		
		try {
			invTransedPivotP = elTrans.inverseTransform(pivotP, invTransedPivotP );
						
		} catch ( Exception ex ) {
			ex.printStackTrace();
		}

		cont.halfWidth = invTransedPivotP.getX();
		cont.halfHeight = invTransedPivotP.getY();
	}
	// in case of group select, the pivotX, pivotY, and pivotP are all set
	return;
  }

  void setPivotParam() {
	for ( int i=0; i < selectedElements.size(); i++ ){
		SelectedElementContainer cont = ((SelectedElementContainer)selectedElements.get(i));
		cont.halfWidth = 0;
		cont.halfHeight = 0;
	}
	currEl = ((SelectedElementContainer)selectedElements.get(0)).element;
	Shape selRec = currEl.getFinalShape();
	
	pivotP = currEl.getFinalLeftFrontPoint();
	pivotX = pivotP.getX();
	pivotY = pivotP.getY();
	
	fullWidth *= 2;
	//	startAngle = Math.atan2((startDragY-pivotY),(startDragX-pivotX));
	//	origStartAngle = startAngle;	
  }

}
